package com.infra.server.controller;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.infra.server.api.Result;
import com.infra.server.entity.SysResource;
import com.infra.server.entity.SysRole;
import com.infra.server.entity.SysRouter;
import com.infra.server.config.LoginUserHolder;
import com.infra.server.service.SysResourceService;
import com.infra.server.service.SysRoleService;
import com.infra.server.service.SysRouterService;
import com.infra.server.utils.ConstantUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author: zzd
 * @Date: 2020/9/19 16:57
 * @Description: 角色相关接口
 */
@RestController
@Api(value = "SysRoleController",tags = "角色相关接口")
@RequestMapping("/role")
public class SysRoleController {

    @Resource
    private SysRoleService sysRoleService;
    @Resource
    private LoginUserHolder loginUserHolder;
    @Resource
    private SysRouterService sysRouterService;
    @Resource
    private SysResourceService sysResourceService;

    @ApiOperation(value = "根据角色获取角色的动态路由",notes = "0")
    @GetMapping("/async_routes")
    public Result getAsyncRoutesByRoles(@RequestParam String roles) {
        Map<String,Object> map = new HashMap<>();
        List<SysRouter> sysRouterList = new ArrayList<>();

        boolean isAdmin = loginUserHolder.isAdmin();
        if (isAdmin) {
            sysRouterList = sysRouterService.list();
        } else {
            Object[] roleName = roles.split(",");
            // 批量查询角色信息
            QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("name",roleName);
            List<SysRole> roleList = sysRoleService.list(queryWrapper);
            if (ObjectUtil.isNotEmpty(roleList)) {
                // 取出角色数组的id
                List<Integer> roleIds = roleList.stream().map(SysRole::getId).collect(Collectors.toList());
                // 根据角色id查询对应的路由列表
                sysRouterList = sysRoleService.getRouterByRoleIds(roleIds);
            }
        }
        List<Object> asyncRoutes = filterRouter(sysRouterList);

        map.put("asyncRoutes",asyncRoutes);
        return Result.ok().data(map).message("获取角色动态路由成功！");
    }

    /**
     * 递归遍历构造路由树
     */
    public List<Object> filterRouter(List<SysRouter> sysRouterList) {
        List<Object> list = new ArrayList<>();
        for (SysRouter r : sysRouterList) {
            // 根节点父id为0
            if (r.getParentId() == 0) {
                routerData(sysRouterList, list, r);
            }
        }
        return list;
    }

    /**
     * 获取子路由
     */
    public List<Object> getChildren(Integer id,List<SysRouter> sysRouterList){
        List<Object> list = new ArrayList<>();
        for (SysRouter r : sysRouterList) {
            if (r.getParentId().equals(id)) {
                routerData(sysRouterList, list, r);
            }
        }
        return list;
    }

    /**
     * 路由结构
     * 这里之所以不用hutool的树工具是为了把id和parentId两个属性移除掉，返回符合前端路由的数据结构
     */
    private void routerData(List<SysRouter> sysRouterList, List<Object> list, SysRouter r) {
        JSONObject object = new JSONObject();
        object.put("path",r.getPath());
        object.put("component",r.getComponent());
        if (!StrUtil.hasEmpty(r.getRedirect())) {
            object.put("redirect",r.getRedirect());
        }
        if (!StrUtil.hasEmpty(r.getName())) {
            object.put("name",r.getName());
        }
        Map<String,Object> meta = new HashMap<>();
        meta.put("title",r.getTitle());
        meta.put("icon",r.getIcon());
        if (r.getKeepAlive()) {
            meta.put("keepAlive",r.getKeepAlive());
        }
        if (!StrUtil.hasEmpty(r.getTitle()) || !StrUtil.hasEmpty(r.getIcon())) {
            object.put("meta", meta);
        }
        if (r.getHidden()) {
            object.put("hidden",r.getHidden());
        }
        if (r.getAlwaysShow()) {
            object.put("alwaysShow",r.getAlwaysShow());
        }
        List<Object> children = getChildren(r.getId(),sysRouterList);
        if (children.size() > 0) {
            object.put("children",children);
        }
        list.add(object);
    }

    /**
     * @param name 角色名称
     * @param size 每页大小
     * @param current 当前页
     * @Return Sysrole
     */
    @ApiOperation(value = "获取系统角色",notes = "1")
    @GetMapping("/list")
    public Result getRole(@RequestParam(required = false) String name,@RequestParam(required = false) Integer current,@RequestParam(required = false) Integer size) {
        Map<String,Object> map = new HashMap<>();
        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        if (!StrUtil.hasEmpty(name)) {
            queryWrapper.like("name",name);
        }
        if (current != null && size != null) {
            Page<SysRole> page = new Page<>(current,size);
            IPage<SysRole> list = sysRoleService.page(page,queryWrapper);
            map.put("list",list);
        } else {
            List<SysRole> list = sysRoleService.list(queryWrapper);
            map.put("list",list);
        }
        return Result.ok().data(map).message("获取角色列表成功");
    }

    @ApiOperation(value = "添加或修改角色信息",notes = "1")
    @PostMapping("/save")
    @Transactional(rollbackFor = Exception.class)
    public Result saveOrUpdateRole(@RequestBody SysRole sysRole) {
        if (sysRole.getId() == null) {
            QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("name",sysRole.getName());
            SysRole sysRole1 = sysRoleService.getOne(queryWrapper);
            if (ObjectUtil.isNotNull(sysRole1)) {
                return Result.error().message("该角色已存在，请重新添加！");
            } else {
                boolean a = sysRoleService.save(sysRole);
                if (a) {
                    // 自动分配默认权限
                    if (ObjectUtil.isNotEmpty(sysRole.getId())) {
                        List<SysRouter> sysRouterList = sysRouterService.list(new LambdaQueryWrapper<SysRouter>()
                                .eq(SysRouter::getRouterType,2));
                        if (ObjectUtil.isNotEmpty(sysRouterList)) {
                            List<Object> list = new ArrayList<>();
                            for (SysRouter s : sysRouterList) {
                                Map<String,Object> map = new HashMap<>();
                                map.put("roleId",sysRole.getId());
                                map.put("routerId",s.getId());
                                list.add(map);
                            }
                            sysRoleService.saveRoleRouter(sysRole.getId(),list);
                        }

                        List<SysResource> sysResourceList = sysResourceService.list(new LambdaQueryWrapper<SysResource>()
                                .eq(SysResource::getResourceType,2));
                        if (ObjectUtil.isNotEmpty(sysResourceList)) {
                            for (SysResource s : sysResourceList) {
                                if (s.getOwner().endsWith(",")) {
                                    s.setOwner(s.getOwner() + sysRole.getName());
                                } else {
                                    s.setOwner(StrUtil.isNotEmpty(s.getOwner()) ? s.getOwner() + "," + sysRole.getName() : sysRole.getName());
                                }
                            }

                            sysResourceService.updateBatchById(sysResourceList);
                        }
                    }
                    return Result.ok().message("添加角色成功");
                } else {
                    return Result.error().message("添加角色失败，请重试!");
                }
            }
        } else {
            boolean b = sysRoleService.updateById(sysRole);
            if (b) {
                return Result.ok().message("修改角色信息成功");
            } else {
                return Result.error().message("修改角色信息失败，请重试!");
            }
        }
    }

    @ApiOperation(value = "根据id删除角色",notes = "1")
    @GetMapping("/delete")
    public Result deleteRole(@RequestParam Integer id) {
        String roleName = sysRoleService.getById(id).getName();
        if (roleName.equals(ConstantUtil.ADMINISTRATOR_ROLE)) {
            return Result.error().message("管理员角色禁止删除!");
        } else {
            boolean a = sysRoleService.deleteRoleByRoleId(id,roleName);
            if (a) {
                return Result.ok().message("删除角色成功");
            } else {
                return Result.error().message("删除角色失败，请重试！");
            }
        }
    }

    @ApiOperation(value = "根据角色id获取角色权限",notes = "1")
    @GetMapping("/permission")
    public Result getPermissionByRoleId(@RequestParam Integer roleId) {
        Map<String,Object> map = new HashMap<>();
        // 获取路由id
        List<Object> routerIds = sysRoleService.getRouterByRoleId(roleId);
        map.put("routerIds",routerIds);
        // 获取角色id
        List<Long> userIds = sysRoleService.getUserByRoleId(roleId);
        map.put("userIds",userIds);
        return Result.ok().data(map).message("获取角色相关权限成功");
    }

    @ApiOperation(value = "分配权限",notes = "1")
    @PostMapping("/permission/save")
    public Result savePermission(@RequestBody Map<String,Object> map) {
        int a = sysRoleService.savePermission(map);
        if (a > 0) {
            return Result.ok().message("权限分配成功");
        } else {
            return Result.error().message("权限分配失败，请重试！");
        }
    }

    @ApiOperation(value = "获取默认权限",notes = "1")
    @GetMapping("/permission/default")
    public Result getDefaultPermission() {
        // 获取自动权限
        List<SysRouter> sysRouterList = sysRouterService.list(new LambdaQueryWrapper<SysRouter>()
                .eq(SysRouter::getRouterType,2));
        List<Integer> routerIds = sysRouterList.stream().map(SysRouter::getId).collect(Collectors.toList());

        Map<String,Object> map = new HashMap<>();
        map.put("routerIds",routerIds);
        return Result.ok().data(map);
    }

    @ApiOperation(value = "设置默认权限",notes = "1")
    @PostMapping("/permission/default/save")
    public Result saveDefaultPermission(@RequestBody Map<String,Object> map) {
       sysRoleService.saveDefaultPermission(map);
       return Result.ok().message("默认权限分配成功");
    }

}
